package com.lw.smartquiz.assess;

import cn.hutool.json.JSONUtil;
import com.lw.smartquiz.common.ErrorCode;
import com.lw.smartquiz.exception.BusinessException;
import com.lw.smartquiz.model.dto.question.QuestionContentDTO;
import com.lw.smartquiz.model.entity.App;
import com.lw.smartquiz.model.entity.Question;
import com.lw.smartquiz.model.entity.ScoringResult;
import com.lw.smartquiz.model.entity.UserAnswer;
import com.lw.smartquiz.model.enums.AppTypeEnum;
import com.lw.smartquiz.model.enums.ScoringStrategyEnum;
import com.lw.smartquiz.model.vo.QuestionVO;
import com.lw.smartquiz.service.QuestionService;
import com.lw.smartquiz.service.ScoringResultService;

import javax.annotation.Resource;
import java.util.List;

/**
 * 自定义的得分类应用的评判策略
 */
@AssessStrategyConfig(appType = AppTypeEnum.SCORE, strategyType = ScoringStrategyEnum.CUSTOM)
public class CustomScoreAssessStrategy implements AssessStrategy {
    @Resource
    private QuestionService questionService;
    @Resource
    private ScoringResultService scoringResultService;

    @Override
    public UserAnswer doScore(List<String> choices, App app) {
        // 1.通过app获取对应的题目，结果
        Long appId = app.getId();
        Question question = questionService.lambdaQuery().eq(Question::getAppId, appId).one();
        QuestionVO questionVO = QuestionVO.objToVo(question);
        // 题目列表
        List<QuestionContentDTO> questionList = questionVO.getQuestionContent();
        // 按结果分数降序排列的结果列表
        List<ScoringResult> scoringResultList = scoringResultService.lambdaQuery().eq(ScoringResult::getAppId, appId).orderByDesc(ScoringResult::getResultScoreRange).list();

        // 2.计算用户总得分
        int totalScore = 0;
        //这里如果用choices.size()，有可能大于questionList.size()，导致数组越界
        int size = questionList.size();
        for (int i = 0; i < size; i++) {
            //用户这一题的选择
            String choice = choices.get(i);
            //这一题的所有选项
            List<QuestionContentDTO.Option> options = questionList.get(i).getOptions();
            for (QuestionContentDTO.Option option : options) {
                // 如果用户选择了这个选项，则增加相应的得分
                if (choice.equals(option.getKey())) {
                    totalScore += option.getScore();
                    break;
                }
            }
        }

        // 3.从高到低遍历结果分数，找到第一个大于的结果分数，返回
        for (ScoringResult scoringResult : scoringResultList) {
            if (totalScore >= scoringResult.getResultScoreRange()){
                UserAnswer userAnswer = new UserAnswer();
                userAnswer.setAppId(appId);
                userAnswer.setAppType(app.getAppType());
                userAnswer.setScoringStrategy(app.getScoringStrategy());
                userAnswer.setChoices(JSONUtil.toJsonStr(choices));
                userAnswer.setResultId(scoringResult.getId());
                userAnswer.setResultName(scoringResult.getResultName());
                userAnswer.setResultDesc(scoringResult.getResultDesc());
                userAnswer.setResultPicture(scoringResult.getResultPicture());
                userAnswer.setResultScore(totalScore);
                return userAnswer;
            }
        }
        throw new BusinessException(ErrorCode.OPERATION_ERROR, "没有找到对应的得分结果");
    }
}
